# coding: utf-8
import os
import sysconfig
from setuptools import setup, find_packages
from setuptools.command.build_py import build_py as _build_py
from setuptools.command.build_ext import build_ext as _build_ext

SKIP_CYTHON = os.environ.get('SKIP_CYTHON', '0') == '1'

EXCLUDE_FILES = [
    'app/serve.py',
    'calc_manager/ray/ray_manager.py',
    'calc_manager/ray/remote_task.py',
    'calc_manager/ray/__init__.py',
]

EXCLUDE_DIRS = [
    'calc_manager/plugins_inner'
]

def get_ext_paths(root_dir, exclude_files, exclude_dirs):
    """get filepaths for compilation"""
    paths = []
    for root, dirs, files in os.walk(root_dir):
        if any(root.startswith(ex_dir) for ex_dir in exclude_dirs):
            continue
        
        for filename in files:
            if os.path.splitext(filename)[1] != '.py':
                continue
            file_path = os.path.join(root, filename)
            if file_path in exclude_files:
                continue
            paths.append(file_path)
    return paths

#def get_ext_paths(root_dir, exclude_files):
#    """get filepaths for compilation"""
#    paths = []
#
#    for root, dirs, files in os.walk(root_dir):
#        for filename in files:
#            if os.path.splitext(filename)[1] != '.py':
#                continue
#
#            file_path = os.path.join(root, filename)
#            if file_path in exclude_files:
#                continue
#
#            # Check against each pattern in exclude_patterns to see if it matches
#            #if any(fnmatch.fnmatch(file_path, pattern) for pattern in exclude_files):
#            #    continue
#
#
#            paths.append(file_path)
#    return paths
#

# noinspection PyPep8Naming
class build_ext(_build_ext):
    def finalize_options(self):
        super().finalize_options()

# noinspection PyPep8Naming
class build_py(_build_py):
    def run(self):
        self.run_command('build_ext')
        _build_py.run(self)
        # After running build_py, remove .py files that have corresponding .so files
        if self.build_lib:
            ext_suffix = sysconfig.get_config_var('EXT_SUFFIX')
            for package in self.packages:
                package_dir = self.get_package_dir(package)
                build_dir = os.path.join(self.build_lib, package_dir)
                for root, _, files in os.walk(build_dir):
                    for filename in files:
                        if filename.endswith('.py'):
                            py_filepath = os.path.join(root, filename)
                            so_filepath = py_filepath.replace('.py', ext_suffix)
                            if os.path.exists(so_filepath):
                                print(f"Removing {py_filepath} as {so_filepath} exists")
                                try:
                                    os.remove(py_filepath)
                                except OSError as e:
                                    print(f"Error removing {py_filepath}: {e}")

    def find_package_modules(self, package, package_dir):
        ext_suffix = sysconfig.get_config_var('EXT_SUFFIX')
        modules = super().find_package_modules(package, package_dir)
        filtered_modules = []
        for (pkg, mod, filepath) in modules:
            if os.path.exists(filepath.replace('.py', ext_suffix)):
                continue
            filtered_modules.append((pkg, mod, filepath, ))
        return filtered_modules

if not SKIP_CYTHON:
    from Cython.Build import cythonize
    extensions = cythonize(
        get_ext_paths('calc_manager', EXCLUDE_FILES, EXCLUDE_DIRS),
        compiler_directives={'language_level': 3}
    )
else:
    extensions = []

setup(
    name='sh-computing-calc-manager',
    version='0.1.0',
    packages=find_packages(),
    ext_modules=extensions,
    #ext_modules=cythonize(
    #    get_ext_paths('calc_manager', EXCLUDE_FILES, EXCLUDE_DIRS),
    #    compiler_directives={'language_level': 3}
    #),
    cmdclass={
        'build_py': build_py,
        'build_ext': build_ext,
    }
)